import cv2
import numpy as np

# 载入视频文件
cap = cv2.VideoCapture('bike.mp4')

# 定义压缩比列表
keep_list = [0.5, 0.05, 1]

def apply_compression(fft_shift, compression_ratio):
    magnitude = np.abs(fft_shift)
    threshold = np.percentile(magnitude, 100 - 100 * compression_ratio)
    mask = magnitude > threshold
    compressed_fft_shift = fft_shift * mask
    return compressed_fft_shift

while True:
    # 读取一帧图像
    ret, frame = cap.read()

    # 如果没有读取到帧则退出循环
    if not ret:
        break

    # 灰度影像
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 傅里叶变换
    fft = np.fft.fft2(gray_frame)
    fft_shift = np.fft.fftshift(fft)

    for keep_ratio in keep_list:
        # 应用压缩
        compressed_fft_shift = apply_compression(fft_shift, keep_ratio)

        # 逆傅里叶变换
        compressed_ifft_shift = np.fft.ifftshift(compressed_fft_shift)
        compressed_img = np.fft.ifft2(compressed_ifft_shift)
        compressed_img = np.abs(compressed_img)

        # 转换为8位无符号整数类型
        compressed_img_uint8 = cv2.normalize(compressed_img, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)

        # 显示压缩后的图像
        cv2.imshow(f'Compressed Image (Keep Ratio: {keep_ratio})', compressed_img_uint8)

    # 等待按键事件或一定的时间，然后关闭所有窗口
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

# 释放视频文件
cap.release()

# 关闭所有窗口
cv2.destroyAllWindows()